home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1995, Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the name of Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
- * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
- */
- /*----------------------------------------------------------------------------
- *
- * file : lmwrap.c
- *
- * Author : Yusuf Attarwala
- * Date : Apr 95
- *
- * wrappers for irisGL style lmbind and lmdef calls
- * to be used in openGL applications
- *
- *---------------------------------------------------------------------------*/
- #include "lmwrap.h"
- #include "globals.h"
-
- #define UNDEFINED -99
-
- /* max number of indices for each category */
- #define MAXLIGHT 16
- #define MAXLMODEL 6
- #define MAXMATERIAL 32
-
- /* define some unique non zero number to initialize our tables */
- #define LMDEF_INIT -765123
-
- /* actual number of indices used by the application*/
- static int nLight, nLModel, nMaterial;
-
- /* look up table between indices provided and indices used */
- static int lutLight[MAXLIGHT],
- lutLModel[MAXLMODEL],
- lutMaterial[MAXMATERIAL];
-
- /* pointers to tables for storing lmdef info */
- static float *lightTable[MAXLIGHT],
- *lModelTable[MAXLMODEL],
- *materialTable[MAXMATERIAL];
-
- /* max number of entries in each table */
- #define NLIGHTENTRY 17
- #define NMATERIALENTRY 21
- #define NLMODELENTRY 9
-
- /* these are the offsets of specific values in tables */
-
- #define MATAMBIENT 0 /* 4 floats */
- #define MATDIFFUSE 4 /* 4 floats */
- #define MATALPHA 7 /* 1 float */ /* 4th component of diffuse */
- #define MATSPECULAR 8 /* 4 floats */
- #define MATEMISSION 12 /* 4 floats */
- #define MATSHININESS 16 /* 1 float */
- #define MATCOLORINDEXES 17 /* 3 float */
-
- #define LITAMBIENT 0 /* 4 floats */
- #define LITLCOLOR 4 /* 4 floats */
- #define LITPOSITION 8 /* 4 floats */
- #define LITSPOTDIRECTION 12 /* 3 floats */
- #define LITSPOTLIGHT 15 /* 2 floats */
-
- #define LTMAMBIENT 0 /* 4 floats */
- #define LTMLOCALVIEWER 4 /* 1 float */
- #define LTMTWOSIDE 5 /* 1 float */
- #define LTMATTENUATION 6 /* 2 floats */
- #define LTMATTENUATION2 8 /* 1 floats */
-
- /* base of display lists */
- static GLuint baseLightDL, baseLModelDL, baseMaterialDL;
-
- static int boundLModel;
-
- void
- lmdef(deftype, index, np, props)
- short deftype, index, np;
- float props[];
- {
- static int firstTime = 1;
- int i;
- int isDefined;
- GLuint dList;
- float *table,*tbl,*prp;
-
- GLenum face = GL_FRONT;
-
- if (firstTime) {
- firstTime = 0;
-
- baseLightDL = glGenLists(MAXLIGHT);
- baseLModelDL = glGenLists(MAXLMODEL);
- baseMaterialDL = glGenLists(MAXMATERIAL);
-
- nLight = nLModel = nMaterial = 0;
- }
-
- /* for each deftype do the following :
-
- check if lmdef has been called before with the same index.
- if so, blow away the appropriate display list and create new one.
- if not, create a new DL and update, the lut etc
-
- */
-
- switch(deftype) {
- case DEFLIGHT :
- isDefined = UNDEFINED;
-
- for (i=0;i<MAXLIGHT;i++) {
- if (index == lutLight[i]) {
- isDefined = i;
- break;
- }
- }
-
- if (isDefined == UNDEFINED) {
- if (nLModel >= MAXLIGHT) {
- printf("ran out of light tables \n");
- return;
- }
-
- lutLight[nLight] = index;
- lightTable[nLight] = (float *) malloc(sizeof(float) * NLIGHTENTRY);
- table = lightTable[nLight];
-
- /* insert some non zero unique value to initialize */
- for (i=0;i<NLIGHTENTRY;i++) {
- *(table+i) = LMDEF_INIT;
- }
- table = lightTable[nLight];
- nLight++;
- }
- else {
- table = lightTable[isDefined];
- }
-
- if (props == NULL) {
-
- /* just create table with defaults */
-
- /* purge previous definitions */
-
- for (i=0;i<NLIGHTENTRY;i++) {
- *(table+i) = LMDEF_INIT;
- }
-
- /* these are the light model AMBIENT parameters */
-
- tbl = table + LITAMBIENT;
-
- *tbl++ = 0.2;
- *tbl++ = 0.2;
- *tbl++ = 0.2;
- *tbl++ = 1.0;
- }
- else {
- /* create/update tables with new values */
-
- prp = (float *)&props[0];
-
- while (*prp != LMNULL) {
- if (*prp == AMBIENT) {
- prp++;
- tbl = table + LITAMBIENT;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- *tbl++ = 1.0;
- }
- else if (*prp == LCOLOR) {
- prp++;
- tbl = table + LITLCOLOR;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- *tbl++ = 1.0;
- }
- else if (*prp == POSITION) {
- prp++;
- tbl = table + LITPOSITION;
- for (i=0;i<4;i++)*tbl++ = *prp++;
- }
- else if (*prp == SPOTDIRECTION) {
- prp++;
- tbl = table + LITSPOTDIRECTION;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- }
- else if (*prp == SPOTLIGHT) {
- prp++;
- tbl = table + LITSPOTLIGHT;
- for (i=0;i<2;i++)*tbl++ = *prp++;
- }
- else {
- printf("invalid field [%d] in lmdef LIGHT \n",*prp++);
- }
- } /* while */
- }
-
- /*
-
- Reason for not creating display list for light tables :
-
- no display list is created here, because in lmdef of light,
- we don't know which light will be bound with index
- e.g GL_LIGHT0 or GL_LIGHT1 or...
- the display list can be only created if we have that
- info, because glLightfv(...) needs it,
- therefore, just store the values in our table and
- use them in lmbind in immediate mode
-
- */
- break;
-
- case DEFLMODEL :
- isDefined = UNDEFINED;
-
- for (i=0;i<MAXLMODEL;i++) {
- if (index == lutLModel[i]) {
- isDefined = i;
- break;
- }
- }
-
- if (isDefined == UNDEFINED) {
- if (nLModel >= MAXLMODEL) {
- printf("ran out of light model tables \n");
- return;
- }
-
- dList = baseLModelDL + nLModel;
- lutLModel[nLModel] = index;
- lModelTable[nLModel] = (float *)
- malloc(sizeof(float) * NLMODELENTRY);
-
-
- table = lModelTable[nLModel];
-
- /* insert some non zero unique value to initialize */
- for (i=0;i<NLMODELENTRY;i++) {
- *(table+i) = LMDEF_INIT;
- }
-
- table = lModelTable[nLModel];
-
- nLModel++;
- }
- else {
-
- dList = baseLModelDL + isDefined;
- glDeleteLists(dList,1);
- table = lModelTable[isDefined];
-
- }
-
- if (props == NULL) {
-
- /* just create table with defaults */
-
- /* purge previous definitions */
-
- for (i=0;i<NLMODELENTRY;i++) {
- *(table+i) = LMDEF_INIT;
- }
-
- /* these are the light model AMBIENT parameters */
-
- tbl = table + LTMAMBIENT;
-
- *tbl++ = 0.2;
- *tbl++ = 0.2;
- *tbl++ = 0.2;
- *tbl++ = 1.0;
- }
- else {
- /* create/update tables with new values */
-
- prp = (float *)&props[0];
-
- while (*prp != LMNULL) {
- if (*prp == AMBIENT) {
- prp++;
- tbl = table + LTMAMBIENT;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- *tbl++ = 1.0;
- }
- else if (*prp == LOCALVIEWER) {
- prp++;
- tbl = table + LTMLOCALVIEWER;
- *tbl = *prp++;
- }
- else if (*prp == TWOSIDE) {
- prp++;
- tbl = table + LTMTWOSIDE;
- *tbl = *prp++;
- }
- else if (*prp == ATTENUATION) {
- prp++;
- tbl = table + LTMATTENUATION;
- for (i=0;i<2;i++)*tbl++ = *prp++;
- }
- else if (*prp == ATTENUATION2) {
- prp++;
- tbl = table + LTMATTENUATION2;
- *tbl = *prp++;
- }
- else {
- printf("invalid field [%d] in lmdef LMODEL \n",*prp++);
- }
- } /* while */
- }
-
- /* generate the list from our tables */
- glNewList(dList,GL_COMPILE);
-
- if (*(table + LTMAMBIENT) != LMDEF_INIT) {
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT,(table + LTMAMBIENT));
- }
- if (*(table + LTMLOCALVIEWER) != LMDEF_INIT) {
- glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,*(table+LTMLOCALVIEWER));
- }
- if (*(table + LTMTWOSIDE) != LMDEF_INIT) {
- glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,*(table + LTMTWOSIDE));
- }
- /* ATTENUATIONS are taken care in lmbind of lights */
-
- glEndList();
- break;
- case DEFMATERIAL :
- isDefined = UNDEFINED;
-
- for (i=0;i<MAXMATERIAL;i++) {
- if (index == lutMaterial[i]) {
- isDefined = i;
- break;
- }
- }
-
- if (isDefined == UNDEFINED) {
- if (nMaterial >= MAXMATERIAL) {
- printf("ran out of mateial tables \n");
- return;
- }
-
- dList = baseMaterialDL + nMaterial;
- lutMaterial[nMaterial] = index;
- materialTable[nMaterial] = (float *)
- malloc(sizeof(float) * NMATERIALENTRY);
-
-
- table = materialTable[nMaterial];
-
- /* insert some non zero unique value to initialize */
- for (i=0;i<NMATERIALENTRY;i++) {
- *(table+i) = LMDEF_INIT;
- }
-
- nMaterial++;
- }
- else {
-
- dList = baseMaterialDL + isDefined;
- glDeleteLists(dList,1);
- table = materialTable[isDefined];
-
- }
-
- if (props == NULL) {
-
- /* just create table with defaults */
-
- /* purge previous definitions */
-
- for (i=0;i<NMATERIALENTRY;i++) {
- *(table+i) = LMDEF_INIT;
- }
-
- /* these are the AMBIENT parameters */
-
- tbl = table + MATAMBIENT;
-
- *tbl++ = 0.2;
- *tbl++ = 0.2;
- *tbl++ = 0.2;
- *tbl++ = 1.0;
- }
- else {
- /* create/update tables with new values */
-
- prp = (float *)&props[0];
-
- while (*prp != LMNULL) {
- if (*prp == ALPHA) {
- prp++; /* can't increment in if */
- tbl = table + MATALPHA;
- *tbl = *prp++;
- }
- else if (*prp == AMBIENT) {
- prp++;
- tbl = table + MATAMBIENT;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- *tbl++ = 1.0;
- }
- else if (*prp == DIFFUSE) {
- prp++;
- tbl = table + MATDIFFUSE;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- if (*tbl != LMDEF_INIT) *tbl++ = 1.0;
- }
- else if (*prp == SPECULAR) {
- prp++;
- tbl = table + MATSPECULAR;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- *tbl++ = 1.0;
- }
- else if (*prp == EMISSION) {
- prp++;
- tbl = table + MATEMISSION;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- *tbl++ = 1.0;
- }
- else if (*prp == SHININESS) {
- prp++;
- tbl = table + MATSHININESS;
- *tbl = *prp++;
- }
- else if (*prp == COLORINDEXES) {
- prp++;
- tbl = table + MATCOLORINDEXES;
- for (i=0;i<3;i++)*tbl++ = *prp++;
- }
- else {
- printf("invalid field [%d] in lmdef MATERIAL \n",*prp++);
- }
- } /* while */
- }
-
- /* generate the list from our tables */
- glNewList(dList,GL_COMPILE);
-
- if (*(table + MATAMBIENT) != LMDEF_INIT) {
- glMaterialfv(face,GL_AMBIENT,(table + MATAMBIENT));
- }
- if (*(table + MATDIFFUSE) != LMDEF_INIT) {
- glMaterialfv(face,GL_DIFFUSE,(table + MATDIFFUSE));
- }
- if (*(table + MATSPECULAR) != LMDEF_INIT) {
- /* in irisGL if the shininess is zero or undefined,
- then even specular is not added */
- if (*(table + MATSHININESS) != 0.0 &&
- *(table + MATSHININESS) != LMDEF_INIT) {
- glMaterialfv(face,GL_SPECULAR,(table + MATSPECULAR));
- }
- }
- if (*(table + MATEMISSION) != LMDEF_INIT) {
- glMaterialfv(face,GL_EMISSION,(table + MATEMISSION));
- }
- if (*(table + MATSHININESS) != LMDEF_INIT) {
- glMaterialf(face,GL_SHININESS,*(table + MATSHININESS));
- }
- if (*(table + MATCOLORINDEXES) != LMDEF_INIT) {
- glMaterialfv(face,GL_COLOR_INDEXES,(table + MATCOLORINDEXES));
- }
-
- glEndList();
-
- break;
- default :
- printf("invalid type for lmdef [%d] \n",deftype);
- return;
- }
- }
-
- void
- lmbind(target,index)
- short target,index;
- {
- int i;
- GLuint dList;
- int lightOffset;
- GLboolean lightOn;
- float *table,*tbl,*prp;
-
- GLenum face = GL_BACK;
-
- switch(target) {
- case LIGHT0 :
- case LIGHT1 :
- case LIGHT2 :
- case LIGHT3 :
- case LIGHT4 :
- case LIGHT5 :
- case LIGHT6 :
- case LIGHT7 :
-
- lightOffset = GL_LIGHT0 + ( target - LIGHT0) ;
- if (index == 0) {
- glDisable(lightOffset);
-
- /* if all the lights are off, then disable lighting */
- lightOn = False;
- for (i=0;i<8;i++) {
- if (glIsEnabled(GL_LIGHT0 + i)) {
- lightOn = True;
- break;
- }
- }
- if (!lightOn) glDisable(GL_LIGHTING);
- }
- else {
-
- dList = UNDEFINED;
- for (i=0;i<nLight;i++) {
- if (lutLight[i] == index) {
- dList = i;
-
- break;
- }
- }
-
- if (dList == UNDEFINED) {
- printf("lmbind-LIGHT, index [%d] not defined\n",index);
- return;
- }
- else {
- /* we don't have a display list here, see reason
- in lmdef light */
-
- table = lightTable[dList];
-
- if (*(table + LITAMBIENT) != LMDEF_INIT) {
- glLightfv(lightOffset,GL_AMBIENT,(table + LITAMBIENT));
- }
- if (*(table + LITLCOLOR) != LMDEF_INIT) {
- glLightfv(lightOffset,GL_DIFFUSE,(table + LITLCOLOR));
- }
- if (*(table + LITPOSITION) != LMDEF_INIT) {
- glLightfv(lightOffset,GL_POSITION,(table + LITPOSITION));
- }
- if (*(table + LITSPOTDIRECTION) != LMDEF_INIT) {
- glLightfv(lightOffset,GL_SPOT_DIRECTION,
- (table+LITSPOTDIRECTION));
- }
- if (*(table + LITSPOTLIGHT) != LMDEF_INIT) {
- glLightf(lightOffset,GL_SPOT_EXPONENT,
- *(table+LITSPOTLIGHT));
- glLightf(lightOffset,GL_SPOT_CUTOFF,
- *(table+LITSPOTLIGHT+1));
- }
-
- /* see if the current light model has attentuation,
- if so, apply it to the light
-
- boundLModel points to the table of currently bound
- lighting model
-
- */
-
- if (boundLModel != UNDEFINED) {
- table = lModelTable[boundLModel];
-
- if (*(table + LTMATTENUATION) != LMDEF_INIT) {
- glLightf(lightOffset,GL_CONSTANT_ATTENUATION,
- *(table+LTMATTENUATION));
- glLightf(lightOffset,GL_LINEAR_ATTENUATION,
- *(table+LTMATTENUATION+1));
- }
- if (*(table + LTMATTENUATION2) != LMDEF_INIT) {
- glLightf(lightOffset,GL_QUADRATIC_ATTENUATION,
- *(table+LTMATTENUATION2));
- }
- }
- }
-
- if (!glIsEnabled(GL_LIGHTING)) glEnable(GL_LIGHTING);
- }
- break;
- case LMODEL :
- if (index == 0) {
- /* in irisGL, turning off a material or light model,
- turns lighting off */
- if (glIsEnabled(GL_LIGHTING)) glDisable(GL_LIGHTING);
- }
- else {
- /* from the lut, find the display list */
-
- boundLModel = dList = UNDEFINED;
- for (i=0;i<nLModel;i++) {
- if (lutLModel[i] == index) {
- dList = baseLModelDL + i;
- boundLModel = i;
- break;
- }
- }
-
- if (dList == UNDEFINED) {
- printf("lmbind-LMODEL, index [%d] not defined\n",index);
- return;
- }
- else {
- glCallList(dList);
- if (!glIsEnabled(GL_LIGHTING)) glEnable(GL_LIGHTING);
- }
- }
- break;
- case MATERIAL :
- if (index == 0) {
- /* in irisGL, turning off a material or light model,
- turns lighting off */
- if (glIsEnabled(GL_LIGHTING)) glDisable(GL_LIGHTING);
- }
- else {
- /* from the lut, find the display list */
-
- dList = UNDEFINED;
- for (i=0;i<nMaterial;i++) {
- if (lutMaterial[i] == index) {
- dList = baseMaterialDL + i;
- break;
- }
- }
- /*
- printf("FRONTMAT %d \n",dList-baseMaterialDL);
- */
-
- if (dList == UNDEFINED) {
- printf("lmbind-MATERIAL, index [%d] not defined\n",index);
- return;
- }
- else {
- glCallList(dList);
- if (!glIsEnabled(GL_LIGHTING)) glEnable(GL_LIGHTING);
- }
- }
- break;
- case BACKMATERIAL :
-
- /* display list has been created with GL_FRONT,
- assuming BACKMATERIAL is not used frequently,
- use the values from tables in immediate mode
- instead of creating storing display list */
-
- if (index != 0) {
- /* index = 0 has no effect on lighting ON,OFF so
- ignore it */
-
- /* from the lut, find the display list */
-
- dList = UNDEFINED;
- for (i=0;i<nMaterial;i++) {
- if (lutMaterial[i] == index) {
- dList = i;
- break;
- }
- }
-
- if (dList == UNDEFINED) {
- printf("lmbind-BACKMATERIAL, index [%d] not defined\n",index);
- return;
- }
- else {
- if (!glIsEnabled(GL_LIGHTING)) glEnable(GL_LIGHTING);
- }
-
- table = materialTable[dList];
- /*
- printf("BACKMAT %d \n",dList);
- */
-
- if (*(table + MATAMBIENT) != LMDEF_INIT) {
- glMaterialfv(face,GL_AMBIENT,(table + MATAMBIENT));
- }
- if (*(table + MATDIFFUSE) != LMDEF_INIT) {
- glMaterialfv(face,GL_DIFFUSE,(table + MATDIFFUSE));
- }
- if (*(table + MATSPECULAR) != LMDEF_INIT) {
- /* in irisGL if the shininess is zero or undefined,
- then even specular is not added */
- if (*(table + MATSHININESS) != 0.0 &&
- *(table + MATSHININESS) != LMDEF_INIT) {
- glMaterialfv(face,GL_SPECULAR,(table + MATSPECULAR));
- }
- }
- if (*(table + MATEMISSION) != LMDEF_INIT) {
- glMaterialfv(face,GL_EMISSION,(table + MATEMISSION));
- }
- if (*(table + MATSHININESS) != LMDEF_INIT) {
- glMaterialf(face,GL_SHININESS,*(table + MATSHININESS));
- }
- if (*(table + MATCOLORINDEXES) != LMDEF_INIT) {
- glMaterialfv(face,GL_COLOR_INDEXES,(table + MATCOLORINDEXES));
- }
- }
- break;
- default :
- printf("invalid target for lmbind [%d] \n",target);
- return;
- }
- }
-